package com.time.social.controller;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.time.social.config.SocialConfig;
import com.time.social.entity.Result;
import com.time.social.entity.SocialTokenResponse;
import com.time.social.entity.SocialUserInfo;
import com.time.social.enums.SocialTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 微信登录控制器
 *
 * @author: HuangQi
 * @date: Created in 2025/01/XX
 * @description: 微信登录控制器
 */
@Slf4j
@RestController
@RequestMapping("/social/wx")
public class WxLoginController extends AbstractSocialLoginController {

    @Autowired
    private SocialConfig socialConfig;

    private final Gson gson = new Gson();

    /**
     * 微信授权URL
     */
    private static final String WX_AUTH_URL = "https://open.weixin.qq.com/connect/qrconnect";

    /**
     * 微信获取Token URL
     */
    private static final String WX_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

    /**
     * 微信获取用户信息 URL
     */
    private static final String WX_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";

    /**
     * 跳转到微信授权页面
     */
    @GetMapping("/login")
    public RedirectView login() {
        return super.login();
    }

    /**
     * 微信回调处理
     */
    @GetMapping("/callback")
    public Result<Object> callback(@RequestParam("code") String code,
                                    @RequestParam(value = "state", required = false) String state) {
        return super.callback(code, state);
    }

    @Override
    protected String getAuthUrl(String state) {
        SocialConfig.WxConfig wxConfig = socialConfig.getWx();
        if (wxConfig == null) {
            throw new RuntimeException("微信配置未找到");
        }

        String redirectUri = buildCallbackUrl();
        String encodedRedirectUri = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8);

        // 构建授权URL
        StringBuilder url = new StringBuilder(WX_AUTH_URL);
        url.append("?appid=").append(wxConfig.getAppId());
        url.append("&redirect_uri=").append(encodedRedirectUri);
        url.append("&response_type=code");
        url.append("&scope=snsapi_login");
        url.append("&state=").append(state);
        url.append("#wechat_redirect");

        return url.toString();
    }

    @Override
    protected SocialTokenResponse getAccessToken(String code) {
        try {
            SocialConfig.WxConfig wxConfig = socialConfig.getWx();
            if (wxConfig == null) {
                throw new RuntimeException("微信配置未找到");
            }

            String redirectUri = buildCallbackUrl();
            String encodedRedirectUri = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8);

            // 构建获取token的URL
            StringBuilder url = new StringBuilder(WX_TOKEN_URL);
            url.append("?appid=").append(wxConfig.getAppId());
            url.append("&secret=").append(wxConfig.getAppSecret());
            url.append("&code=").append(code);
            url.append("&grant_type=authorization_code");

            // 发送请求
            String response = httpGet(url.toString());
            log.info("微信获取token响应: {}", response);

            // 解析响应
            JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
            SocialTokenResponse tokenResponse = new SocialTokenResponse();

            if (jsonObject.has("access_token")) {
                tokenResponse.setAccessToken(jsonObject.get("access_token").getAsString());
                tokenResponse.setExpiresIn(jsonObject.has("expires_in") ? 
                    jsonObject.get("expires_in").getAsLong() : null);
                tokenResponse.setRefreshToken(jsonObject.has("refresh_token") ? 
                    jsonObject.get("refresh_token").getAsString() : null);
                tokenResponse.setScope(jsonObject.has("scope") ? 
                    jsonObject.get("scope").getAsString() : null);
            } else {
                tokenResponse.setError(jsonObject.has("errcode") ? 
                    jsonObject.get("errcode").getAsString() : "unknown");
                tokenResponse.setErrorDescription(jsonObject.has("errmsg") ? 
                    jsonObject.get("errmsg").getAsString() : "获取token失败");
            }

            return tokenResponse;
        } catch (Exception e) {
            log.error("微信获取access_token失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取微信access_token失败", e);
        }
    }

    @Override
    protected SocialUserInfo getUserInfo(String accessToken) {
        try {
            // 先获取openid
            String openIdUrl = WX_TOKEN_URL + "?access_token=" + accessToken;
            String openIdResponse = httpGet(openIdUrl);
            log.info("微信获取openid响应: {}", openIdResponse);

            JsonObject openIdJson = gson.fromJson(openIdResponse, JsonObject.class);
            String openId = openIdJson.has("openid") ? 
                openIdJson.get("openid").getAsString() : null;
            String unionId = openIdJson.has("unionid") ? 
                openIdJson.get("unionid").getAsString() : null;

            if (openId == null) {
                throw new RuntimeException("获取openid失败");
            }

            // 构建获取用户信息的URL
            StringBuilder url = new StringBuilder(WX_USER_INFO_URL);
            url.append("?access_token=").append(accessToken);
            url.append("&openid=").append(openId);

            // 发送请求
            String response = httpGet(url.toString());
            log.info("微信获取用户信息响应: {}", response);

            // 解析响应
            JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
            SocialUserInfo userInfo = new SocialUserInfo();

            if (jsonObject.has("openid")) {
                userInfo.setOpenId(jsonObject.get("openid").getAsString());
                userInfo.setUnionId(unionId);
                userInfo.setNickname(jsonObject.has("nickname") ? 
                    jsonObject.get("nickname").getAsString() : null);
                userInfo.setAvatar(jsonObject.has("headimgurl") ? 
                    jsonObject.get("headimgurl").getAsString() : null);
                userInfo.setGender(jsonObject.has("sex") ? 
                    (jsonObject.get("sex").getAsInt() == 1 ? "男" : "女") : null);
                userInfo.setLocation(jsonObject.has("province") && jsonObject.has("city") ? 
                    jsonObject.get("province").getAsString() + " " + 
                    jsonObject.get("city").getAsString() : null);
                userInfo.setRawData(response);
            } else {
                throw new RuntimeException("获取用户信息失败: " + 
                    (jsonObject.has("errmsg") ? jsonObject.get("errmsg").getAsString() : "未知错误"));
            }

            return userInfo;
        } catch (Exception e) {
            log.error("微信获取用户信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取微信用户信息失败", e);
        }
    }

    @Override
    protected SocialTypeEnum getSocialType() {
        return SocialTypeEnum.WX;
    }

    @Override
    protected String getRedirectUri() {
        return socialConfig.getWx() != null ? 
            socialConfig.getWx().getRedirectUri() : "/social/wx/callback";
    }
}

